package com._5704.website.service.ServiceImpl;

import com._5704.website.entity.ToEmail;
import com._5704.website.entity.User;
import com._5704.website.exception.WebsiteException;
import com._5704.website.exception.WebsiteExceptionEnum;
import com._5704.website.form.UserForm;
import com._5704.website.mapper.UserMapper;
import com._5704.website.service.IUserService;
import com._5704.website.shiro.JwtToken;
import com._5704.website.util.*;
import com._5704.website.vo.userVO.UserVO;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author Yiyoung
 * @since 2021-07-25
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
    @Resource
    private UserMapper userMapper;

    @Value("${email.subject}")
    private  String subject;

    @Value("${email.code.expiredTime}")
    private  long expiredTime;

    @Value("${email.code.length}")
    private  int length;

    @Autowired
    private TemplateEngine templateEngine;

    @Resource
    private FileUtil fileUtil;

    /**
     * 获取最近登陆时间
     * @param phoneNum 用户号码
     * @return
     */
//    @Override
//    public Date getLastLoginTime(String phoneNum){
//        String key = "userInfo:"+phoneNum;
//        Date time;
//        if (RedisUtil.isExist(key)){
//            time = (Date) RedisUtil.getValue(key);
//        }else{
//           time = userMapper.getLastLoginTime(phoneNum);
//        }
//        return time;
//    }


    /**
     * 设置token
     * @param id 用户id
     * @return token类
     */
    @Override
    public JwtToken setToken(String id) {
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        String token = JwtUtil.createJwt(id);
        return new JwtToken(token);
    }

    /**
     * 验证用户
     * @param loginPwd 登录密码
     * @param pwd 密码
     */
    @Override
    public void verifyPwd(String loginPwd, String pwd) {
        //密码不正确
        if(loginPwd.compareTo(pwd) != 0){
            throw new WebsiteException(WebsiteExceptionEnum.USER_NOT_MACH_PASSWORD);
        }
    }

    /**
     * 插入用户
     * @param user 用户
     */
    @Override
    public void insertUser(User user) {

        RedisUtil.setValue("userInfo:"+user.getUserId(),user);
        userMapper.insert(user);
    }

    /**
     * 判断用户是否存在
     * @param id 用户id
     * @return
     */
//    @Override
//    public boolean userIsExists(String id) {
//        User user = userMapper.selectById(id);
//        return user != null;
//    }

    /**
     * 更新用户
     * @param user 用户
     */
    @Override
    public void updateUser(User user) {
        // 存入缓存
        RedisUtil.setValue("userInfo:"+user.getUserId(),user);
        userMapper.updateById(user);
    }

    /**
     * 获得用户
     * @param id 用户id
     * @return yonhu
     */
    @Override
    public User getUser(String id) {
        User user;
        // 判断缓存中是否拥有用户
        if (RedisUtil.isExist("userInfo:"+id)){
            user = (User) RedisUtil.getValue("userInfo:"+id);
        }else{
            user = userMapper.selectById(id);
            if (user == null) {
                throw new WebsiteException(WebsiteExceptionEnum.USER_NOT_FOUND);
            }
            RedisUtil.setValue("userInfo:"+id,user);
        }


        return user;
    }

    /**
     * 设置修改信息
     * @param user 用户
     * @param userForm 修改信息表单
     */
    @Override
    public void setModifyData(User user, UserForm userForm) {
        user.setAcademy(userForm.getAcademy())
                .setName(userForm.getName())
                .setMajor(userForm.getMajor())
                .setStuId(userForm.getStuId())
                .setSex(userForm.getSex())
                .setUserName(userForm.getUserName())
                .setIntroduction(userForm.getIntroduction())
                .setConnect(userForm.getConnect());
    }

    /**
     * 更新权限
     * @param user 用户id
     * @param perms 权限
     */
//    @Override
//    public void updateAuthority(User user, int perms) {
//        user.setPerms(perms);
//
//        userMapper.updateById(user);
//    }



    /**
     * 是否为管理员
     *
     * @param user 用户id
     * @return
     */
    @Override
    public boolean isAdmin(User user) {


        return user.getPerms() == 2;
    }

    /**
     * 是否为内部成员
     *
     * @param user 用户id
     * @return
     */
    @Override
    public boolean isInsider(User user) {

        return user.getPerms() >= 1;
    }

    /**
     * 是否是黑名单用户
     *
     * @param user
     * @return
     */
    @Override
    public boolean isBalckLister(User user) {


        return user.getPerms() == -1;
    }

    /**
     * 获取用户
     * @param num  数量
     * @param page 页数
     * @return 用户列表
     */
    @Override
    public List<User> getUsers(int page, int num) {
        List<User> userList = userMapper.getUsers(page, num);

        return userList;
    }

    /**
     * 获得返回的VO
     *
     * @param user 用户
     * @return VO
     */
    @Override
    public UserVO getUserVO(User user) {

        return new UserVO()
                    .setId(user.getUserId())
                    .setAcademy(user.getAcademy())
                    .setMajor(user.getMajor())
                    .setCreateTime(user.getCreateTime())
                    .setName(user.getName())
                    .setPerms(user.getPerms())
                    .setSex(user.getSex())
                    .setStuId(user.getStuId())
                    .setUserName(user.getUserName())
                    .setIntroduction(user.getIntroduction())
                    .setConnect(user.getConnect())
                    .setAvatar(user.getAvatar())
                    .setLastLoginTime(user.getLastLoginTime());
    }


    /**
     * 密码加密
     *
     * @param pwd  密码
     * @param salt 盐
     * @return 加密密码
     */
    @Override
    public String encryptionPwd(String pwd, String salt) {
        // 密码加密
        return String.valueOf(new Md5Hash(pwd,salt,1024));
    }

    /**
     * 登出
     * @param id 用户id
     */
    public void logOut(String id){
        userMapper.setLastLoginTime(id);
    }


    /**
     * 获得数量
     *
     * @return
     */
    @Override
    public int getNum() {
        return userMapper.getNum();
    }

    /**
     * 搜索
     *
     * @param name 名字
     * @param page 页面
     * @param num  数量
     * @return
     */
    @Override
    public List<User> getUserByName(String name, int page, int num) {
        return userMapper.getUserByName(name,page,num);
    }

    /**
     * 获得数量
     *
     * @param name
     * @return
     */
    @Override
    public int getNum(String name) {
        return userMapper.getSearchNum(name);
    }




    /**
     * 更新头像
     *  @param file   文件
     * @param userId 用户id
     * @return
     */
    @Override
    public String uploadAvatar(MultipartFile file, String userId) {

        if (file.isEmpty()){
            throw new WebsiteException(WebsiteExceptionEnum.FILE_ERROR);
        }
//        String originalFilename = file.getOriginalFilename();
        // 设置数据库文件名
        String DataBaseFileName = "avatar/"+userId + ".png";
        // 工具类上传
        fileUtil.upload(file,DataBaseFileName);
        // 修改数据库
        userMapper.updateAvatar(DataBaseFileName,userId);
        RedisUtil.setValue("userInfo:"+userId,userMapper.selectById(userId));
        return DataBaseFileName;
    }

    /**
     * 获得注册的email
     *
     * @return
     */
    @Override
    @Async
    public void sendEmail(ToEmail email) {

        EmailUtil.send(email);

    }

    /**
     * 获得注册的email
     *
     * @return
     * @param userId 用户id
     * @param doSomething 做什么
     */
    @Override
    public ToEmail getEmail(String userId, String doSomething) {

        // 获取随机码
        String code = GetRandomUtil.getRandomCode(length);
        // 存入缓存
        RedisUtil.setValue(userId+doSomething, code,expiredTime);

        // 获取邮件内容
        Context context = new Context();
        context.setVariable("code", code);
        context.setVariable("type", doSomething);
        String content = templateEngine.process("emailTemplate", context);  //  模板： 参数


        return new ToEmail()
                .setUser(userId)
                .setSubject(subject)
                .setContent(content);
    }
}
